/* USER CODE BEGIN Header */
/**
 ******************************************************************************
 * File Name          : freertos.c
 * Description        : Code for freertos applications
 ******************************************************************************
 * @attention
 *
 * Copyright (c) 2023 STMicroelectronics.
 * All rights reserved.
 *
 * This software is licensed under terms that can be found in the LICENSE file
 * in the root directory of this software component.
 * If no LICENSE file comes with this software, it is provided AS-IS.
 *
 ******************************************************************************
 */
/* USER CODE END Header */

/* Includes ------------------------------------------------------------------*/
#include "FreeRTOS.h"
#include "task.h"
#include "main.h"
#include "cmsis_os.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "event_groups.h"
#include <stdio.h>
/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
#define BITMASK_KEY_LEFT	(0b00000001<<2)
#define BITMASK_KEY_RIGHT	(0b00000001<<0)
/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN Variables */

/* USER CODE END Variables */
/* Definitions for Task_Buzzer */
osThreadId_t Task_BuzzerHandle;
const osThreadAttr_t Task_Buzzer_attributes = { .name = "Task_Buzzer",
		.stack_size = 128 * 4, .priority = (osPriority_t) osPriorityNormal, };
/* Definitions for Task_LED */
osThreadId_t Task_LEDHandle;
const osThreadAttr_t Task_LED_attributes = { .name = "Task_LED", .stack_size =
		128 * 4, .priority = (osPriority_t) osPriorityBelowNormal, };
/* Definitions for Task_ScanKeys */
osThreadId_t Task_ScanKeysHandle;
const osThreadAttr_t Task_ScanKeys_attributes =
		{ .name = "Task_ScanKeys", .stack_size = 128 * 4, .priority =
				(osPriority_t) osPriorityAboveNormal, };
/* Definitions for eventGroup */
osEventFlagsId_t eventGroupHandle;
const osEventFlagsAttr_t eventGroup_attributes = { .name = "eventGroup" };

/* Private function prototypes -----------------------------------------------*/
/* USER CODE BEGIN FunctionPrototypes */

/* USER CODE END FunctionPrototypes */

void AppTask_Buzzer(void *argument);
void AppTask_LED(void *argument);
void AppTask_ScanKeys(void *argument);

void MX_FREERTOS_Init(void); /* (MISRA C 2004 rule 8.1) */

/**
 * @brief  FreeRTOS initialization
 * @param  None
 * @retval None
 */
void MX_FREERTOS_Init(void) {
	/* USER CODE BEGIN Init */

	/* USER CODE END Init */

	/* USER CODE BEGIN RTOS_MUTEX */
	/* add mutexes, ... */
	/* USER CODE END RTOS_MUTEX */

	/* USER CODE BEGIN RTOS_SEMAPHORES */
	/* add semaphores, ... */
	/* USER CODE END RTOS_SEMAPHORES */

	/* USER CODE BEGIN RTOS_TIMERS */
	/* start timers, add new ones, ... */
	/* USER CODE END RTOS_TIMERS */

	/* USER CODE BEGIN RTOS_QUEUES */
	/* add queues, ... */
	/* USER CODE END RTOS_QUEUES */

	/* Create the thread(s) */
	/* creation of Task_Buzzer */
	Task_BuzzerHandle = osThreadNew(AppTask_Buzzer, NULL,
			&Task_Buzzer_attributes);

	/* creation of Task_LED */
	Task_LEDHandle = osThreadNew(AppTask_LED, NULL, &Task_LED_attributes);

	/* creation of Task_ScanKeys */
	Task_ScanKeysHandle = osThreadNew(AppTask_ScanKeys, NULL,
			&Task_ScanKeys_attributes);

	/* USER CODE BEGIN RTOS_THREADS */
	/* add threads, ... */
	/* USER CODE END RTOS_THREADS */

	/* Create the event(s) */
	/* creation of eventGroup */
	eventGroupHandle = osEventFlagsNew(&eventGroup_attributes);

	/* USER CODE BEGIN RTOS_EVENTS */
	/* add events, ... */
	/* USER CODE END RTOS_EVENTS */

}

/* USER CODE BEGIN Header_AppTask_Buzzer */
/**
 * @brief  Function implementing the Task_Buzzer thread.
 * @param  argument: Not used
 * @retval None
 */
/* USER CODE END Header_AppTask_Buzzer */
void AppTask_Buzzer(void *argument) {
	/* USER CODE BEGIN AppTask_Buzzer */
	/* Infinite loop */
	for (;;) {
		xEventGroupWaitBits(eventGroupHandle, BITMASK_KEY_LEFT | BITMASK_KEY_RIGHT,
				pdTRUE, pdTRUE, portMAX_DELAY);
		for (int i = 0; i < 10; ++i) {
			Buzzer_Toggle();
			vTaskDelay(pdMS_TO_TICKS(500));
		}
	}
	/* USER CODE END AppTask_Buzzer */
}

/* USER CODE BEGIN Header_AppTask_LED */
/**
 * @brief Function implementing the Task_LED thread.
 * @param argument: Not used
 * @retval None
 */
/* USER CODE END Header_AppTask_LED */
void AppTask_LED(void *argument) {
	/* USER CODE BEGIN AppTask_LED */
	/* Infinite loop */
	for (;;) {
		xEventGroupWaitBits(eventGroupHandle, BITMASK_KEY_LEFT | BITMASK_KEY_RIGHT,
				pdTRUE, pdTRUE, portMAX_DELAY);
		for (int i = 0; i < 10; ++i) {
			LED1_Toggle();
			vTaskDelay(pdMS_TO_TICKS(500));
		}
	}
	/* USER CODE END AppTask_LED */
}

/* USER CODE BEGIN Header_AppTask_ScanKeys */
/**
 * @brief Function implementing the Task_ScanKeys thread.
 * @param argument: Not used
 * @retval None
 */
/* USER CODE END Header_AppTask_ScanKeys */
void AppTask_ScanKeys(void *argument) {
	/* USER CODE BEGIN AppTask_ScanKeys */
	KEYS keyCode = KEY_NONE;
	/* Infinite loop */
	for (;;) {
		uint8_t temp_str[20];
		sprintf(temp_str, "Current event bits = %02X", xEventGroupGetBits(eventGroupHandle));
		lcd_show_str(10, 130, 24, temp_str, RED);

		keyCode = ScanPressedKey(50);
		switch (keyCode) {
		case KEY_LEFT:
			xEventGroupSetBits(eventGroupHandle, BITMASK_KEY_LEFT);
			break;
		case KEY_RIGHT:
			xEventGroupSetBits(eventGroupHandle, BITMASK_KEY_RIGHT);
			break;
		case KEY_DOWN:
			xEventGroupClearBits(eventGroupHandle, BITMASK_KEY_LEFT | BITMASK_KEY_RIGHT);
			break;
		default:
			break;
		}
		if (keyCode == KEY_NONE) {
			vTaskDelay(pdMS_TO_TICKS(50));
		} else {
			vTaskDelay(pdMS_TO_TICKS(200));
		}
	}
	/* USER CODE END AppTask_ScanKeys */
}

/* Private application code --------------------------------------------------*/
/* USER CODE BEGIN Application */

/* USER CODE END Application */

